﻿using System;
using System.Collections.Generic;
using System.Linq;
using Mvc3App.Domain.Entities;
using Mvc3App.Domain.Repository;

namespace Mvc3App.RepositoryMemory
{
    public class MemoryRespository<TEntity> : IRepository<TEntity, int> where TEntity : BaseEntity
    {
        static IDictionary<Type, IDictionary<object, TEntity>> _dictionary;
        
        static IDictionary<Type, IDictionary<object, TEntity>> Dictionary
        {
            get
            {
                if (_dictionary == null)
                {
                    _dictionary = new Dictionary<Type, IDictionary<object, TEntity>>();
                }
                return _dictionary;
            }
        }

        #region IRepository

        public TEntity GetOne(int id)
        {
            if (Dictionary.ContainsKey(typeof(TEntity)) && Dictionary[typeof(TEntity)].ContainsKey(id))
                return Dictionary[typeof(TEntity)][id];
            
            return default(TEntity);
        }

        public void Add(TEntity entity)
        {
            if (!Dictionary.ContainsKey(typeof(TEntity)))
                Dictionary[typeof(TEntity)] = new Dictionary<object, TEntity>();
 
            // uso reflection para setear el id porque el setter no es publico
            entity.GetType().BaseType.GetProperty("Id").SetValue(entity, Dictionary[typeof(TEntity)].Count + 1, null);
 
            Dictionary[typeof(TEntity)].Add(entity.Id, entity);
        }

        public void Update(TEntity entity)
        {
            if (Dictionary.ContainsKey(typeof(TEntity)) && Dictionary[typeof(TEntity)].ContainsKey(entity.Id))
                Dictionary[typeof(TEntity)][entity.Id] = entity;
        }

        public void Delete(TEntity entity)
        {
            if (Dictionary.ContainsKey(typeof(TEntity)) && Dictionary[typeof(TEntity)].ContainsKey(entity.Id))
                Dictionary[typeof(TEntity)].Remove(entity.Id);
        }

        public long Count()
        {
            return this.GetAll().Count();
        }

        public IEnumerable<TEntity> GetSlice(int slice, int quantity, string order, bool ascending)
        {
            if (!Dictionary.ContainsKey(typeof(TEntity)))
                return new List<TEntity>();

            return Dictionary[typeof(TEntity)].Values.ToList().GetRange(slice, quantity);
        }

        #endregion

        #region Custom Methods

        public IEnumerable<TEntity> GetAll()
        {
            IList<TEntity> all = new List<TEntity>();
            
            if (Dictionary.ContainsKey(typeof(TEntity)))
            {
                foreach (TEntity t in Dictionary[typeof(TEntity)].Values)
                {
                    all.Add(t);
                }
            }
            return all;
        }

        #endregion
    }
}
